home *** CD-ROM | disk | FTP | other *** search
/ Light ROM 1 / LIGHT-ROM 1 (Amiga Library Services)(1994).iso / ffdisks / d939.lha / ExtraCmds / source_etc.lha / src / Usage.c < prev   
C/C++ Source or Header  |  1993-10-22  |  7KB  |  257 lines

  1. /*   ---------------------------------      -------     
  2.  *   |\  | | | | |  |.| |   \|  |/ /|\      |||||||     
  3.  *   | | | |/  | |\ |/  |/|  |\ |/  |    ?  ---+---  =< 
  4.  *   | | | |   | |  |     |  |  |   |     \qqqqqqqqq/   
  5.  *   ---------------------------------  ~~~~~~~~~~~~~~~~
  6.  *  Usage - Estimate disk space usage.
  7.  *  Copyright (C) 1993 Torsten Poulin
  8.  *
  9.  *  This program is free software; you can redistribute it and/or modify
  10.  *  it under the terms of the GNU General Public License as published by
  11.  *  the Free Software Foundation; either version 2 of the License, or
  12.  *  (at your option) any later version.
  13.  *
  14.  *  This program is distributed in the hope that it will be useful,
  15.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  16.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17.  *  GNU General Public License for more details.
  18.  *
  19.  *  You should have received a copy of the GNU General Public License
  20.  *  along with this program; if not, write to the Free Software
  21.  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  22.  *
  23.  *  The author can be contacted by s-mail at
  24.  *    Torsten Poulin
  25.  *    Banebrinken 99, 2, 77
  26.  *    DK-2400 Copenhagen NV
  27.  *    DENMARK
  28.  *
  29.  * $Id: Usage.c,v 37.5 93/03/01 12:35:20 Torsten Rel $
  30.  * $Log:    Usage.c,v $
  31.  * Revision 37.5  93/03/01  12:35:20  Torsten
  32.  * Changed all occurrences of "struct DosBase *" to "struct DosLibrary *"
  33.  * 
  34.  * Revision 37.4  93/02/27  14:07:53  Torsten
  35.  * Corrected silly bug: I had "swapped" the values of 'rc' for failed 
  36.  * calls to AllocVec() and ParseArgs() in entrypoint(), resulting
  37.  * in an out of memory message being produced by malformed command lines.
  38.  * 
  39.  * Revision 37.3  93/02/26  11:49:03  Torsten
  40.  * Replaced the return code check in entrypoint() with
  41.  * a call to printErrorMsg(), unfortunately resulting in a 28 bytes
  42.  * bigger executable ;-(
  43.  * It now prints a reasonable error message if the global structure
  44.  * cannot be allocated.
  45.  * 
  46.  * Revision 37.2  93/02/25  18:39:11  Torsten
  47.  * Tightened the code a bit.
  48.  * 
  49.  * Revision 37.1  93/02/16  18:17:11  Torsten
  50.  * Initial revision.
  51.  * 
  52.  */
  53.  
  54. #include <exec/types.h>
  55. #include <exec/memory.h>
  56. #include <dos/dos.h>
  57. #include <dos/dosextens.h>
  58. #include <dos/dostags.h>
  59. #include <dos/dosasl.h>
  60. #include <clib/exec_protos.h>
  61. #include <clib/dos_protos.h>
  62. #ifdef __SASC
  63. #include <pragmas/exec_pragmas.h>
  64. #include <pragmas/dos_pragmas.h>
  65. #endif
  66. #include <string.h>
  67. #include "tastlib.h"
  68. #include "usage_rev.h"
  69.  
  70. #define PROGNAME "Usage"
  71. #define TEMPLATE "DIR/M,BRIEF/S,NOHEAD/S,NOTOTAL/S"
  72. #define OPT_DIR     0
  73. #define OPT_BRIEF   1
  74. #define OPT_NOHEAD  2
  75. #define OPT_NOTOTAL 3
  76.  
  77. typedef struct {
  78.   struct DosLibrary *DOSBase;
  79.   ULONG totalblocks;
  80.   ULONG totalbytes;
  81.   BOOL brief;
  82. } Global;
  83.  
  84. LONG usage(Global *, UBYTE *);
  85.  
  86. char const versionID[] = VERSTAG;
  87. char const copyright[] = "$COPYRIGHT:©1993 Torsten Poulin$";
  88.  
  89. LONG entrypoint(VOID)
  90. {
  91.   struct DosLibrary *DOSBase;
  92.   struct RDArgs *args;
  93.   Global *global;
  94.   LONG   arg[4];
  95.   LONG   rc = RETURN_OK;
  96.   UBYTE  **dir;
  97.   ULONG  count;
  98.  
  99.   if (!(DOSBase = (struct DosLibrary *)    OpenLibrary("dos.library", 37L)))
  100.     return RETURN_FAIL;
  101.  
  102.   if (!(global = AllocVec(sizeof(Global), MEMF_PUBLIC | MEMF_CLEAR)))
  103.     rc = ERROR_NO_FREE_STORE;
  104.   else
  105.   {
  106.     global->DOSBase = DOSBase;
  107.  
  108.     global->totalblocks = global->totalbytes = 0L;
  109.     arg[OPT_DIR] = arg[OPT_BRIEF] = arg[OPT_NOHEAD] = arg[OPT_NOTOTAL] = 0L;
  110.  
  111.     if (!(args = ReadArgs(TEMPLATE, arg, NULL)))
  112.       rc = RETURN_FAIL;
  113.     else
  114.     {
  115.       global->brief = (BOOL) arg[OPT_BRIEF];
  116.       if (!(BOOL) arg[OPT_NOHEAD])
  117.     PutStr("    Blocks      Bytes\n");
  118.  
  119.       if (!arg[OPT_DIR])
  120.     rc = usage(global, "");
  121.       else
  122.       {
  123.     dir = (UBYTE **) arg[OPT_DIR];
  124.     for (count = 0; *dir && rc == RETURN_OK; dir++, count++)
  125.       rc = usage(global, *dir);
  126.     if (count > 1 && !(BOOL) arg[OPT_NOTOTAL])
  127.     {
  128.       PutStr(" --------- ----------\n");
  129.       MyPrintf(global, "%10ld %10ld\n",
  130.            global->totalblocks, global->totalbytes);
  131.     }
  132.       }
  133.       FreeArgs(args);
  134.     }
  135.     FreeVec(global);
  136.   }
  137.   rc = printErrorMsg(rc, PROGNAME, DOSBase);
  138.   CloseLibrary((struct Library *) DOSBase);
  139.   return rc;
  140. }
  141.  
  142.  
  143. LONG calc_usage(Global *global, UBYTE *dir, UBYTE *path,
  144.         ULONG *blocks, ULONG *bytes)
  145. {
  146.   struct DosLibrary *DOSBase = global->DOSBase;
  147.     
  148.   struct FileInfoBlock *m;
  149.   BPTR   lock, oldlock;
  150.   LONG   rc = RETURN_OK;
  151.   LONG   type;
  152.   UBYTE  *currentpath;
  153.   ULONG  fblocks = 0L, fbytes = 0L;
  154.   ULONG  dblocks = 0L, dbytes = 0L;
  155.   ULONG  fudge;
  156.  
  157.   if (!(m = AllocDosObject(DOS_FIB, NULL)))
  158.     rc = ERROR_NO_FREE_STORE;
  159.   else
  160.   {
  161.     if (!(currentpath = AllocVec(strlen(path)+1, MEMF_PUBLIC)))
  162.       rc = ERROR_NO_FREE_STORE;
  163.     else
  164.     {
  165.       if (!(lock = Lock(dir, SHARED_LOCK)))
  166.     rc = RETURN_ERROR;
  167.       else
  168.       {
  169.     oldlock = CurrentDir(lock);
  170.     if (Examine(lock, m))
  171.     {
  172.       type = m->fib_DirEntryType;
  173.       strcpy(currentpath, path);
  174.       if (type < 0 || type == ST_SOFTLINK)
  175.       {
  176.         PrintFault(ERROR_OBJECT_WRONG_TYPE, dir);
  177.         rc = RETURN_WARN;
  178.       }
  179.       else
  180.       {
  181.         while (ExNext(lock, m))
  182.         {
  183.           if (CheckSignal(SIGBREAKF_CTRL_C))
  184.           {
  185.         rc = ERROR_BREAK;
  186.         break;
  187.           }
  188.  
  189.           type = m->fib_DirEntryType;
  190.  
  191.           /* We don't want to handle soft links ;-) */
  192.           if (type != ST_SOFTLINK)
  193.           {
  194.         fblocks += fudge = m->fib_NumBlocks + 1; /* header (?) */
  195.         if (type < 0)
  196.           fbytes += m->fib_Size; /* it's a file */
  197.         else
  198.         {
  199.           /* it's a directory */
  200.           UBYTE *newpath;
  201.  
  202.           if (!(newpath = AllocVec(strlen(currentpath)+108+2,
  203.                        MEMF_PUBLIC)))
  204.           {
  205.             rc = ERROR_NO_FREE_STORE;
  206.             break;
  207.           }
  208.           strcpy(newpath, currentpath);
  209.           AddPart(newpath, m->fib_FileName,
  210.               strlen(currentpath) + 108 + 1);
  211.  
  212.           dblocks = dbytes = 0L;
  213.           rc = calc_usage(global, m->fib_FileName, newpath,
  214.                   &dblocks, &dbytes);
  215.               
  216.           if (!global->brief)
  217.             MyPrintf(global, "%10ld %10ld %s\n",
  218.                  dblocks ? dblocks : dblocks + fudge,
  219.                  dbytes, newpath);
  220.           FreeVec(newpath);
  221.  
  222.           fblocks += dblocks;
  223.           fbytes += dbytes;
  224.  
  225.           if (rc == ERROR_BREAK || rc == ERROR_NO_FREE_STORE)
  226.             break;
  227.         }
  228.           }
  229.         }
  230.         *blocks = fblocks;
  231.         *bytes = fbytes;
  232.       }
  233.     }
  234.     CurrentDir(oldlock);
  235.     UnLock(lock);
  236.       }
  237.       FreeVec(currentpath);
  238.     }
  239.     FreeDosObject(DOS_FIB, m);
  240.   }
  241.   return rc;
  242. }
  243.  
  244.  
  245. LONG usage(Global *global, UBYTE *dir)
  246. {
  247.   ULONG bl = 0L, by = 0L;
  248.   LONG  rc;
  249.  
  250.   if ((rc = calc_usage(global, dir, dir, &bl, &by)) == RETURN_OK)
  251.     MyPrintf(global, "%10ld %10ld %s\n", bl, by, dir);
  252.  
  253.   global->totalblocks += bl;
  254.   global->totalbytes += by;
  255.   return rc;
  256. }
  257.